//+------------------------------------------------------------------+
//|                                                        basic.mq4 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""

#include <stderror.mqh>
#include <stdlib.mqh>

extern string BASICSETTINGS = "BASICSETTINGS";
extern bool exFixPosition = true;
extern double exFixVolume = 0.01;


extern bool exDebug = true;
extern double exTradeRisk = 0.02;

extern bool exTradeByTime = true;

extern int exTradeTimeStart = 6;
extern int exTradeTimeEnd = 21;

extern int exTradeByTimeBreak = 0;
extern int exTradeBreakTimeStart = 8;
extern int exTradeBreakTimeDuration = 1;

extern int exTradeByTimeBreak2 = 0;
extern int exTradeBreakTimeStart2 = 13;
extern int exTradeBreakTimeDuration2 = 1;


string NameFileSound;

int fake(){
   //hide warnings
   if(0==1){
      b_isTradeTime();
      b_debug("na");
      b_alert("na");
      b_setStopLose(0,0);
      b_getPriceByPip(0);
      b_OrderSend("0",0,0,0,0,0,0);
      b_OrderModify(0,0,0,0);
      b_getOpenPositionsByType(0);
   }
}

bool b_isTradeTime(){
   fake();
   if(!exTradeByTime){
      return  (true);
   }
   
   if(exTradeTimeStart > exTradeTimeEnd){
      if(exTradeTimeStart >= TimeHour(Time[0]) && exTradeTimeEnd <= TimeHour(Time[0])){
         return (true);
      }
   }else{
      if(exTradeTimeStart <= TimeHour(Time[0]) && exTradeTimeEnd >= TimeHour(Time[0])){
      
         //return (!(TimeHour(Time[0]) == exTradeBreakTimeStart));
         bool tradeBreak = false;
         if(exTradeByTimeBreak == 1){
            tradeBreak = (TimeHour(Time[0]) >= exTradeBreakTimeStart && MathAbs(exTradeBreakTimeStart - TimeHour(Time[0])) <= exTradeBreakTimeDuration - 1);           
         }
         bool tradeBreak2 = false;
         if(exTradeByTimeBreak2 == 1){
            tradeBreak2 = (TimeHour(Time[0]) >= exTradeBreakTimeStart2 && MathAbs(exTradeBreakTimeStart2 - TimeHour(Time[0])) <= exTradeBreakTimeDuration2 - 1);           
         }
         if(tradeBreak || tradeBreak2){
            return (false);
         }else{
            return (true);
         }
      }
   }

   return (false);
}

void b_debug(string str){
   if(exDebug){
      Print(str);
   }
}

void b_alert(string str){
   if(exDebug){
      Alert(str);
      PlaySound("alert");
   }
}


double b_setStopLose(double stopLoss, int opTrade){

   int digits = MarketInfo(Symbol(),MODE_DIGITS);
   double pp = 1/MathPow(10, digits);

   double StopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL);   
   //kauf
   if (opTrade == 0 || opTrade == OP_BUYSTOP){
      if (Bid - stopLoss > StopLevel*pp){  
      }else{
         stopLoss = Bid - (pp*StopLevel);
      }     
   }else{
      if (stopLoss - Ask > StopLevel*pp){
      }else{
         stopLoss = Ask + (pp*StopLevel);
      }
   }       
   stopLoss = NormalizeDouble(stopLoss,digits);
   return (stopLoss);
}

double b_getPriceByPip(int pips){
   int digits = MarketInfo(Symbol(),MODE_DIGITS);
   double pp = 1/MathPow(10, digits-1);

   return (pips * pp);
}





void b_OrderSend(string symbol, int cmd, double volume, double price, int slippage, double stoploss, double takeprofit, string comment="", int magic=0, datetime expiration=0, color arrow_color=CLR_NONE) {

   if(stoploss!=0){
      stoploss = b_setStopLose(stoploss,cmd);
   }
   if(exFixPosition){
      volume = exFixVolume;
   }
   else if(stoploss!=0){    
      volume = b_getLotSizeByPrice(price,stoploss);
      if(volume < 0.1){
         Alert("sl to far away for the exTradeRisk, also min volume !");
         volume = 0.01;
      }
   }   
   
   double cPrice = 0;  
   double spread = (Ask - Bid) * 2;
   if(cmd == OP_BUYSTOP){
      cPrice = Ask;   
      if((price - cPrice) < spread){
         price = cPrice + spread;
      } 
      //price += Point *100;
   }else if(cmd == OP_SELLSTOP){
      cPrice = Bid; 
      if((cPrice - price) < spread){
         price = cPrice - spread;
      }  
      //price -= Point *100;
   }
   

   int tN = OrderSend(Symbol(),cmd,volume,price,slippage,stoploss,takeprofit,comment,magic,0,arrow_color);

                
   if(tN <= 0){
      int lastError = GetLastError();
      Alert("error(",lastError,"): ",ErrorDescription(lastError));
      double cprice;
      if(cmd == OP_BUY || cmd == OP_BUYSTOP){
         cprice = Ask;   
      }else{
         cprice = Bid;
      }
      
      b_alert("cmd:"+cmd+" cprice:"+cprice +" prefprice: "+price+" sl:"+stoploss +" tp:"+takeprofit+" volume"+volume);
   }
   return (0);

}


void b_OrderModify(int ticket, double price, double stoploss, double takeprofit, datetime expiration = NULL, color arrow_color=CLR_NONE) {
   stoploss = b_setStopLose(stoploss,OrderType());
  
   bool fm = OrderModify(ticket,price,stoploss,takeprofit,expiration,arrow_color); 
   if (fm) {
        //PlaySound(NameFileSound);
   }else{
          int lastError = GetLastError();
          Alert("error(",lastError,"): ",ErrorDescription(lastError));
                double cprice;
      if(OrderType() == OP_BUY || OrderType() == OP_BUYSTOP){
         cprice = Ask;   
      }else{
         cprice = Bid;
      }
      
          b_alert("cmd:"+OrderType()+" cprice:"+cprice +" prefprice: "+price+" sl:"+stoploss +" tp:"+takeprofit );
   }  
}

void b_OrderDeleteByMagic(int magic, int type = - 1){
   for(int k=0; k < OrdersTotal(); k++) {
      if (OrderSelect(k, SELECT_BY_POS, MODE_TRADES)) {
         if ( OrderSymbol()==Symbol() && OrderMagicNumber() == magic && OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP) {
            if(type == OrderType() || type == -1){
               OrderDelete(OrderTicket());       
            }    
         }
      }
   }
}



int b_getOpenPositionsByType(int cmd){
   int result = 0;
   for(int i=0; i < OrdersTotal(); i++) {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
         if ( OrderSymbol()==Symbol()) {
            if(OrderType() == cmd){
               result++;
            }                
         }
      }
   }
   return (result);
}



double b_getLotSize(int pips){

   double lotSize = NormalizeDouble(AccountEquity() *exTradeRisk/(pips*(MarketInfo(Symbol(), MODE_LOTSIZE)/10000)),2);
   Print("lotsize:",DoubleToStr(lotSize,5));
   return (lotSize);
}

double b_getLotSizeByPrice(double prefPrice, double slPrice){
   return (b_getLotSize(MathAbs(prefPrice-slPrice)*MathPow(10,Digits - 1)));
}



